home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995 February: Tool Chest / Dev.CD Feb 95 / Dev.CD Feb 95.toast / Tool Chest / Development Tools & Languages / Dylan Related / Mindy-1.1 (sources only) / mindy-1.1 / interp / buf.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-18  |  5.0 KB  |  196 lines  |  [TEXT/ttxt]

  1. /**********************************************************************\
  2. *
  3. *  Copyright (c) 1994  Carnegie Mellon University
  4. *  All rights reserved.
  5. *  
  6. *  Use and copying of this software and preparation of derivative
  7. *  works based on this software are permitted, including commercial
  8. *  use, provided that the following conditions are observed:
  9. *  
  10. *  1. This copyright notice must be retained in full on any copies
  11. *     and on appropriate parts of any derivative works.
  12. *  2. Documentation (paper or online) accompanying any system that
  13. *     incorporates this software, or any part of it, must acknowledge
  14. *     the contribution of the Gwydion Project at Carnegie Mellon
  15. *     University.
  16. *  
  17. *  This software is made available "as is".  Neither the authors nor
  18. *  Carnegie Mellon University make any warranty about the software,
  19. *  its performance, or its conformity to any specification.
  20. *  
  21. *  Bug reports, questions, comments, and suggestions should be sent by
  22. *  E-mail to the Internet address "gwydion-bugs@cs.cmu.edu".
  23. *
  24. ***********************************************************************
  25. *
  26. * $Header: buf.c,v 1.8 94/07/26 18:31:55 hallgren Exp $
  27. *
  28. * This file implements buffers, a special byte vector used by streams.
  29. *
  30. \**********************************************************************/
  31.  
  32. #include <string.h>
  33.  
  34. #include "mindy.h"
  35. #include "gc.h"
  36. #include "coll.h"
  37. #include "class.h"
  38. #include "module.h"
  39. #include "num.h"
  40. #include "bool.h"
  41. #include "obj.h"
  42. #include "error.h"
  43. #include "list.h"
  44. #include "def.h"
  45. #include "sym.h"
  46. #include "type.h"
  47. #include "vec.h"
  48. #include "str.h"
  49. #include "buf.h"
  50.  
  51. obj_t obj_BufferClass = NULL;
  52.  
  53. static obj_t dylan_buffer_make(obj_t class, obj_t size)
  54. {
  55.     int len;
  56.     obj_t res;
  57.  
  58.     if (!instancep(size, obj_IntegerClass))
  59.     error("Bogus size: for make %=: %=", class, size);
  60.     len = fixnum_value(size);
  61.  
  62.     if (len < 0)
  63.     error("Bogus size: for make %=: %=", class, size);
  64.  
  65.     res = alloc(obj_BufferClass, sizeof(struct buffer) + len);
  66.  
  67.     obj_ptr(struct buffer *, res)->length = len;
  68.  
  69.     return res;
  70. }
  71.  
  72. static obj_t dylan_buffer_size(obj_t buffer)
  73. {
  74.     return make_fixnum(obj_ptr(struct buffer *, buffer)->length);
  75. }
  76.  
  77. static obj_t dylan_buffer_element(obj_t buffer, obj_t index, obj_t def)
  78. {
  79.     int i = fixnum_value(index);
  80.  
  81.     if (0 <= i && i < obj_ptr(struct buffer *, buffer)->length)
  82.     return make_fixnum(buffer_data(buffer)[i]);
  83.     else if (def != obj_Unbound)
  84.     return def;
  85.     else {
  86.     error("No element %= in %=", index, buffer);
  87.     return NULL;
  88.     }
  89. }
  90.  
  91. static obj_t dylan_buffer_element_setter(obj_t val, obj_t buffer, obj_t index)
  92. {
  93.     int i = fixnum_value(index);
  94.  
  95.     if (0 <= i && i < obj_ptr(struct buffer *, buffer)->length)
  96.     buffer_data(buffer)[i] = fixnum_value(val);
  97.     else
  98.     error("No element %= in %=", index, buffer);
  99.  
  100.     return val;
  101. }
  102.  
  103. #ifdef sparc
  104. void *memmove(void *s1, void *s2, size_t n)
  105. {
  106.   char *src = s2;
  107.   char *dest = s1;
  108.   if(src==dest)
  109.     return s1;
  110.   else if(dest < src)
  111.     while(n-- > 0) *dest++ = *src++;
  112.   else {
  113.     src += n - 1;
  114.     dest += n - 1;
  115.     while(n-- > 0) *dest-- = *src--;
  116.   }
  117.   return s1;
  118. }
  119. #endif
  120.  
  121. static obj_t dylan_memcpy(obj_t dst, obj_t dst_off, obj_t src, obj_t src_off,
  122.               obj_t count)
  123. {
  124.     if (dst == src)
  125.     memmove(buffer_data(dst) + fixnum_value(dst_off),
  126.         buffer_data(src) + fixnum_value(src_off),
  127.         fixnum_value(count));
  128.     else
  129.     memcpy(buffer_data(dst) + fixnum_value(dst_off),
  130.            buffer_data(src) + fixnum_value(src_off),
  131.            fixnum_value(count));
  132.  
  133.     return dst;
  134. }
  135.  
  136.  
  137. /* GC stuff. */
  138.  
  139. static int scav_buffer(struct object *ptr)
  140. {
  141.     struct buffer *buffer = (struct buffer *)ptr;
  142.  
  143.     return sizeof(struct buffer) + buffer->length;
  144. }
  145.  
  146. static obj_t trans_buffer(obj_t buffer)
  147. {
  148.     return transport(buffer,
  149.              sizeof(struct buffer)
  150.                + obj_ptr(struct buffer *, buffer)->length);
  151. }
  152.  
  153. void scavenge_buffer_roots(void)
  154. {
  155.     scavenge(&obj_BufferClass);
  156. }
  157.  
  158.  
  159.  
  160. /* Init stuff. */
  161.  
  162. void make_buffer_classes(void)
  163. {
  164.     obj_BufferClass = make_builtin_class(scav_buffer, trans_buffer);
  165. }
  166.  
  167. void init_buffer_classes(void)
  168. {
  169.     init_builtin_class(obj_BufferClass, "<buffer>", obj_VectorClass, NULL);
  170. }
  171.  
  172. void init_buffer_functions(void)
  173. {
  174.     obj_t u;
  175.  
  176.     define_method("element", list2(obj_BufferClass, obj_IntegerClass),
  177.           FALSE, list1(pair(symbol("default"), obj_Unbound)), FALSE,
  178.           obj_IntegerClass, dylan_buffer_element);
  179.     define_method("element-setter",
  180.           list3(obj_IntegerClass, obj_BufferClass, obj_IntegerClass),
  181.           FALSE, obj_False, FALSE, obj_ObjectClass,
  182.           dylan_buffer_element_setter);
  183.     define_method("size", list1(obj_BufferClass), FALSE, obj_False, FALSE,
  184.           obj_IntegerClass, dylan_buffer_size);
  185.     define_method("make", list1(singleton(obj_BufferClass)), FALSE,
  186.           list1(pair(symbol("size"), make_fixnum(4096))),
  187.           FALSE, obj_BufferClass, dylan_buffer_make);
  188.  
  189.     u = type_union(obj_ByteStringClass, obj_ByteVectorClass);
  190.     u = type_union(u, obj_BufferClass);
  191.     define_method("copy-bytes",
  192.           listn(5, u, obj_IntegerClass, u, obj_IntegerClass,
  193.             obj_IntegerClass),
  194.           FALSE, obj_False, FALSE, u, dylan_memcpy);
  195. }
  196.